package com.ruoyi.im.service.impl;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.im.entity.IMSysArea;
import com.ruoyi.im.mapper.IMSysAreaMapper;
import com.ruoyi.im.service.IMAreaService;
import com.ruoyi.im.vo.IMAreaNode;
import com.ruoyi.im.vo.IMAreaTreeVo;
import com.ruoyi.im.vo.IMAreaVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 
 * @author loword
 *
 */
@Service
@Slf4j
public class IMAreaServiceImpl implements IMAreaService {

	@Autowired
    private IMSysAreaMapper areaMapper;
	
	@Override
	public IMSysArea getById(Integer areaId) {
		return areaMapper.selectById(areaId);
	}

	@Override
	public List<IMSysArea> getByShortName(String shortName) {
		return areaMapper.selectByShortName(shortName);
	}

	@Override
	public List<IMSysArea> getByPinyin(String pinyin) {
		return areaMapper.selectByPingYin(pinyin);
	}

	@Override
	public int addArea(IMSysArea area) {
		area.setStatus(0);
		int timeNow = (int) (System.currentTimeMillis()/1000);
		area.setCreateTime(timeNow);
		return areaMapper.insertSysArea(area);
	}

	/*@Override
	public List<IMAreaTreeVo> listArea(IMSysArea area) {
		if(area.getLevelCode() == null) {
			area.setLevelCode(0);
		}
		return areaMapper.selectAll(area);
	}*/

	@Override
	public List<IMAreaTreeVo> listAreaByCityId(IMSysArea area) {
		if(area.getAreaCode() == null) {
			return null;
		}
		area.setLevelCode(2);
		return areaMapper.selectAreaByCityId(area);
	}

	@Override
	public List<IMAreaTreeVo> listAreaByCountyId(IMSysArea area) {
		if(area.getAreaCode() == null) {
			return null;
		}
		area.setLevelCode(3);
		return areaMapper.selectAreaById(area);
	}

	@Override
	public List<IMAreaTreeVo> listAreaByTownId(IMSysArea area) {
		if(area.getAreaCode() == null) {
			return null;
		}
		area.setLevelCode(4);
		return areaMapper.selectAreaById(area);
	}

	@Override
	public List<IMAreaTreeVo> listAreaTree(IMSysArea area) {

		//long start = System.currentTimeMillis();
		List<IMAreaVo> areaTreeList = areaMapper.selectAreaTree(area);
		//List<IMAreaNode> areaTrees = buildAreaTree(areaTreeList);
		//areaTrees.stream().map(IMAreaTreeVo::new).collect(Collectors.toList());
		List<IMAreaTreeVo> areaTrees = eachAreaTree(areaTreeList);
		/*long end = System.currentTimeMillis(); // 记录结束时间
		long exeMillis = end - start;
		log.info("程序执行时间:" + String.valueOf(exeMillis));*/
		return areaTrees;
	}

	/**
	 * 构建前端所需要树结构
	 *
	 * @param areaList 区域列表
	 * @return 树结构列表
	 */
	private List<IMAreaTreeVo> eachAreaTree(List<IMAreaVo> areaList) {
		List<IMAreaTreeVo> countyList = new ArrayList();
		Map<String, Integer> map = new HashMap<>();
		for(int i=0; i<areaList.size(); i++){
			IMAreaVo ri = areaList.get(i);
			String countyKey = ri.getCounty();
			Integer countyIndex = map.get(countyKey);
			if (countyIndex == null) {
				IMAreaTreeVo tree = new IMAreaTreeVo(ri.getCountyCode(), countyKey);
				countyList.add(tree);
				countyIndex = countyList.size() - 1;
				map.put(countyKey, countyIndex);
			}

			String town = ri.getTown();
			String townKey = countyKey + "_" + ri.getTown();
			Integer townIndex = map.get(townKey);
			if (townIndex == null) {
				List<IMAreaTreeVo> children = countyList.get(countyIndex).getList();
				IMAreaTreeVo tree = new IMAreaTreeVo(ri.getTownCode(), town);
				children.add(tree);
				townIndex = children.size() - 1;
				map.put(townKey, townIndex);
			}

			String village = ri.getVillage();
			String villageKey = townKey + "_" + village;
			Integer villageIndex = map.get(villageKey);
			if (villageIndex == null) {
				List<IMAreaTreeVo> children = countyList.get(countyIndex).getList().get(townIndex).getList();
				IMAreaTreeVo tree = new IMAreaTreeVo(ri.getVillageCode(), village);
				children.add(tree);
				villageIndex = children.size() - 1;
				map.put(villageKey, villageIndex);
			}
		}
		return countyList;
	}

	/**
	 * 构建前端所需要树结构
	 *
	 * @param areaList 区域列表
	 * @return 树结构列表
	 */
	@Override
	public List<IMAreaNode> buildAreaTree(List<IMAreaNode> areaList) {
		List<IMAreaNode> returnList = new ArrayList<IMAreaNode>();
		List<String> tempList = new ArrayList<String>();
		for (IMAreaNode areaNode : areaList) {
			tempList.add(areaNode.getAreaCode());
		}
		for (Iterator<IMAreaNode> iterator = areaList.iterator(); iterator.hasNext(); ) {
			IMAreaNode areaNode = (IMAreaNode) iterator.next();
			// 如果是顶级节点, 遍历该父节点的所有子节点
			if (!tempList.contains(areaNode.getParentCode())) {
				recursionFn(areaList, areaNode);
				returnList.add(areaNode);
			}
		}
		if (returnList.isEmpty()) {
			returnList = areaList;
		}
		return returnList;
	}

	/**
	 * 递归列表
	 */
	private void recursionFn(List<IMAreaNode> list, IMAreaNode t) {
		// 得到子节点列表
		List<IMAreaNode> childList = getChildList(list, t);
		t.setChildren(childList);
		for (IMAreaNode tChild : childList) {
			if (hasChild(list, tChild)) {
				// 判断是否有子节点
				Iterator<IMAreaNode> it = childList.iterator();
				while (it.hasNext()) {
					IMAreaNode n = (IMAreaNode) it.next();
					recursionFn(list, n);
				}
			}
		}
	}

	/**
	 * 得到子节点列表
	 */
	private List<IMAreaNode> getChildList(List<IMAreaNode> list, IMAreaNode t) {
		List<IMAreaNode> tlist = new ArrayList<IMAreaNode>();
		Iterator<IMAreaNode> it = list.iterator();
		while (it.hasNext()) {
			IMAreaNode n = (IMAreaNode) it.next();
			if (StringUtils.isNotNull(n.getParentCode()) && n.getParentCode().equals(t.getAreaCode())) {
				tlist.add(n);
			}
		}
		return tlist;
	}

	/**
	 * 判断是否有子节点
	 */
	private boolean hasChild(List<IMAreaNode> list, IMAreaNode t) {
		return getChildList(list, t).size() > 0 ? true : false;
	}

	@Override
	public int updateArea(IMSysArea area) {
		int timeNow = (int) (System.currentTimeMillis()/1000);
		area.setUpdateTime(timeNow);
		return areaMapper.updateSysArea(area);
	}

}
